<template>
  <el-dialog
    v-model="internalVisible"
    width="960px"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    append-to-body
    class="unified-dialog report-config-dialog"
  >
    <template #header>
      <div class="dialog-header">
        <div class="header-text">
          <h3>{{ isEdit ? '编辑报表配置' : '新增报表配置' }}</h3>
          <p>
            根据模板填写参数，保存后可在报表任务列表中查看
          </p>
        </div>
        <el-tag type="success" v-if="currentTemplateMeta">{{ currentTemplateMeta.templateName }}</el-tag>
      </div>
    </template>

    <el-tabs v-model="activeTab" class="config-tabs">
      <el-tab-pane label="基础信息" name="base">
        <section class="form-section">
          <div class="section-title">
            <el-icon><Document /></el-icon>
            <span>基础信息</span>
          </div>
          
          <el-form :model="form" label-width="140px" :disabled="loading">
            <el-form-item label="报表标题" required>
              <el-input
                v-model="form.config_name"
                placeholder="如：CPS 数据同步监控"
                :disabled="loading"
              />
            </el-form-item>

            <el-form-item label="报表模板" required>
              <el-select
                v-model="form.template_code"
                placeholder="请选择模板"
                :disabled="!!props.configId || loading"
                style="width: 100%"
                popper-class="batch-dialog-select-popper"
                popper-append-to-body
              >
                <el-option-group
                  v-for="group in groupedTemplates"
                  :key="group.group"
                  :label="group.label"
                >
                  <el-option
                    v-for="tpl in group.templates"
                    :key="tpl.template_code"
                    :label="tpl.template_name"
                    :value="tpl.template_code"
                  >
                    <span class="template-name">{{ tpl.template_name }}</span>
                  </el-option>
                </el-option-group>
              </el-select>
            </el-form-item>

            <el-form-item label="启用状态">
              <el-switch v-model="form.is_active" :disabled="loading" />
            </el-form-item>

            <el-form-item label="输出格式">
              <el-checkbox-group v-model="form.output_formats" :disabled="loading">
                <el-checkbox label="html">HTML</el-checkbox>
                <el-checkbox label="excel">Excel</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
          </el-form>

          <!-- 定时执行配置 -->
          <div class="schedule-subsection">
            <div class="schedule-subsection-title">
              <el-icon class="schedule-icon"><Clock /></el-icon>
              <span>定时执行配置</span>
              <div class="schedule-switch-wrapper">
                <el-switch 
                  v-model="form.schedule_enabled" 
                  :disabled="loading" 
                  @change="handleScheduleToggle"
                  size="default"
                />
              </div>
            </div>

            <div class="schedule-content">
              <el-input
                ref="cronInputRef"
                v-model="form.schedule_cron"
                placeholder="Cron 表达式, 例如: 0 0 * * *"
                :disabled="!form.schedule_enabled || loading"
                class="cron-input"
                @input="handleCronInputChange"
              />
              
              <!-- 快捷表达式 -->
              <div v-if="form.schedule_enabled" class="cron-quick-presets">
                <div class="quick-presets-header">
                  <el-icon><Star /></el-icon>
                  <span>快捷选择</span>
                </div>
                <div class="quick-presets-buttons">
                  <el-button
                    v-for="preset in cronPresets"
                    :key="preset.value"
                    size="small"
                    :type="form.schedule_cron === preset.value ? 'primary' : 'default'"
                    @click="applyCronPreset(preset.value)"
                  >
                    {{ preset.label }}
                  </el-button>
                </div>
              </div>
              
              <!-- Cron 验证状态和运行时间 -->
              <div v-if="form.schedule_enabled && form.schedule_cron" class="cron-validation">
                <div class="cron-status">
                  <el-tag 
                    :type="cronValid ? 'success' : 'danger'" 
                    size="small"
                  >
                    {{ cronValid ? '表达式有效' : (cronError || '表达式无效') }}
                  </el-tag>
                  <span v-if="cronReadable" class="cron-readable">{{ cronReadable }}</span>
                </div>
                <div v-if="cronValid && cronNextRuns.length > 0" class="cron-next-runs">
                  <el-icon><Clock /></el-icon>
                  <span>未来三次运行：{{ cronNextRuns.join('，') }}</span>
                </div>
              </div>
              
              <div v-if="form.schedule_enabled" class="cron-tip">
                <el-icon><InfoFilled /></el-icon>
                <span>格式：分 时 日 月 周，例如 0 0 * * * 表示每天 00:00 执行</span>
              </div>
            </div>
          </div>
        </section>
      </el-tab-pane>

      <el-tab-pane label="模板参数" name="template">
        <ReportFormCore
          v-model="form.params"
          :template-code="form.template_code"
          ref="formCoreRef"
          @update:model-value="handleParamsChange"
        />
      </el-tab-pane>

      <el-tab-pane label="SQL 预览" name="sql">
        <ReportSqlPreview
          :template-code="form.template_code"
          :params="form.params"
        />
      </el-tab-pane>

      <el-tab-pane label="通知配置" name="notify">
        <NotificationChannelForm
          v-model="notificationForm"
          :webhooks="webhookOptions"
        />
      </el-tab-pane>
    </el-tabs>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose" :disabled="saving">取消</el-button>
        <el-button type="primary" :loading="saving" @click="handleSubmit">
          {{ isEdit ? '保存修改' : '创建配置' }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import { Document, Clock, InfoFilled, Star } from '@element-plus/icons-vue'
import ReportFormCore from './ReportFormCore.vue'
import NotificationChannelForm from '../shared/NotificationChannelForm.vue'
import ReportSqlPreview from '../shared/ReportSqlPreview.vue'
import { getTemplateMeta, listTemplatesByGroup } from '../templates/registry'
// @ts-ignore 缺少类型声明的 JS 模块
import api from '@/utils/api'
// @ts-ignore 缺少类型声明的 JS 模块
import { createLogger } from '@/utils/logger'

const componentLogger = createLogger('ReportConfigEditDialog')

const props = defineProps<{
  modelValue: boolean
  configId?: number | null
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'saved'): void
}>()

const internalVisible = computed({
  get: () => props.modelValue,
  set: (val: boolean) => emit('update:modelValue', val)
})

const form = reactive({
  config_name: '',
  template_code: '',
  is_active: true,
  schedule_enabled: false,
  schedule_cron: '',
  output_formats: ['html'],
  params: {} as Record<string, any>
})

const allowedOutputFormats = ['html', 'excel']

const filterOutputFormats = (formats: any) => {
  const source = Array.isArray(formats) ? formats : ['html']
  const filtered = source.filter((item) => allowedOutputFormats.includes(item))
  return filtered.length ? filtered : ['html']
}

const notificationForm = reactive({
  send_notification: false,
  channels: [] as string[],
  webhook_id: null as number | null,
  wecom_mentioned_list: '',
  wecom_mentioned_all: false
})

const loading = ref(false)
const saving = ref(false)
const groupedTemplates = ref<any[]>([])
const webhookOptions = ref<any[]>([])
const activeTab = ref('base')
const formCoreRef = ref<InstanceType<typeof ReportFormCore> | null>(null)
const cronInputRef = ref()

// Cron 验证相关
const cronValid = ref(false)
const cronError = ref('')
const cronNextRuns = ref<string[]>([])
const cronReadable = ref('')
let cronDebounceTimer: ReturnType<typeof setTimeout> | null = null

// Cron 快捷表达式预设
const cronPresets = [
  { label: '每天 9:00', value: '0 9 * * *' },
  { label: '每天 0:00', value: '0 0 * * *' },
  { label: '工作日 9:00', value: '0 9 * * 1-5' },
  { label: '每小时', value: '0 * * * *' },
  { label: '每 6 小时', value: '0 */6 * * *' },
  { label: '每 30 分钟', value: '*/30 * * * *' },
  { label: '每周一 9:00', value: '0 9 * * 1' },
  { label: '每月 1 号 9:00', value: '0 9 1 * *' }
]

const isEdit = computed(() => !!props.configId)

const currentTemplateMeta = computed(() => getTemplateMeta(form.template_code))

const resetForm = () => {
  form.config_name = ''
  form.template_code = ''
  form.is_active = true
  form.schedule_enabled = false
  form.schedule_cron = ''
  form.output_formats = ['html']
  form.params = {}
  notificationForm.send_notification = false
  notificationForm.channels = []
  notificationForm.webhook_id = null
  notificationForm.wecom_mentioned_all = false
  notificationForm.wecom_mentioned_list = ''
  
  // 重置 Cron 验证状态
  cronValid.value = false
  cronError.value = ''
  cronNextRuns.value = []
  cronReadable.value = ''
  if (cronDebounceTimer) {
    clearTimeout(cronDebounceTimer)
    cronDebounceTimer = null
  }
}

const templatesLoaded = ref(false)
const webhooksLoaded = ref(false)

const fetchTemplates = async () => {
  try {
    const response = await api.get('/reports/templates', {
      params: { page: 1, size: 1000 }
    })
    const rows = response.data.data?.rows || []
    const mappedCodes = new Set<string>()
    const registryGroups = listTemplatesByGroup()
      .map((group) => ({
        ...group,
        templates: group.templates
          .map((tpl) => {
            const remote = rows.find((row: any) => row.template_code === tpl.templateCode)
            if (remote) mappedCodes.add(remote.template_code)
            return {
              template_code: tpl.templateCode,
              template_name: remote?.template_name || tpl.templateName,
              description: remote?.description || tpl.description,
              template_group: remote?.template_group || tpl.group
            }
          })
          .filter(Boolean)
      }))
      .filter((group) => group.templates.length > 0)

    const fallback = rows
      .filter((row: any) => !mappedCodes.has(row.template_code))
      .map((row: any) => ({
        template_code: row.template_code,
        template_name: row.template_name,
        description: row.description,
        template_group: row.template_group || 'others'
      }))

    groupedTemplates.value = [
      ...registryGroups,
      ...(fallback.length
        ? [
            {
              group: 'others',
              label: '其他模板',
              templates: fallback
            }
          ]
        : [])
    ]
    templatesLoaded.value = true
  } catch (error) {
    componentLogger.error('加载模板列表失败', error)
    templatesLoaded.value = false
  }
}

const fetchWebhooks = async () => {
  try {
    const response = await api.get('/reports/webhooks')
    webhookOptions.value = response.data.data || []
    webhooksLoaded.value = true
  } catch (error) {
    componentLogger.error('加载 Webhook 列表失败', error)
    webhooksLoaded.value = false
  }
}

const ensureBaseDataReady = async () => {
  await Promise.all([
    templatesLoaded.value ? Promise.resolve() : fetchTemplates(),
    webhooksLoaded.value ? Promise.resolve() : fetchWebhooks()
  ])
}

const parseParams = (params: any) => {
  if (!params) return {}
  if (typeof params === 'string') {
    try {
      const parsed = JSON.parse(params)
      // 确保返回的是对象，而不是 null 或其他类型
      return parsed && typeof parsed === 'object' ? parsed : {}
    } catch (error) {
      componentLogger.warn('解析 params 失败', error)
      return {}
    }
  }
  // 确保返回的是对象
  return params && typeof params === 'object' ? { ...params } : {}
}

const loadConfigDetail = async (configId: number) => {
  loading.value = true
  try {
    const response = await api.get(`/reports/configs/${configId}`)
    const data = response.data.data
    form.config_name = data.config_name || ''
    form.template_code = data.template_code || ''
    form.is_active = !!data.is_active
    form.schedule_enabled = !!data.schedule_enabled
    form.schedule_cron = data.schedule_cron || ''
    
    // 如果已启用且有 cron 表达式，验证它
    if (form.schedule_enabled && form.schedule_cron) {
      nextTick(() => {
        validateCronFromServer()
      })
    }
    form.output_formats = filterOutputFormats(data.output_formats)
    // 确保 params 始终是对象，不会是 undefined 或 null
    const parsedParams = parseParams(data.params)
    form.params = parsedParams && typeof parsedParams === 'object' ? parsedParams : {}
    
    // 根据模板类型重建时间范围对象
    // 因为保存时 normalizeParams 会删除 time_range/time_filter，只保留顶层和嵌套的时间字段
    if (form.params) {
      // 提取时间范围的辅助函数
      const inferTimeRangeType = (timeStart: string | null, timeEnd: string | null, existingType?: string): string => {
        // 如果有现存的 time_range_type，使用它
        if (existingType) {
          return existingType
        }
        
        // 如果没有时间范围，返回 'all'
        if (!timeStart && !timeEnd) {
          return 'all'
        }
        
        // 根据时间范围推断类型
        if (timeStart && timeEnd) {
          const start = new Date(timeStart)
          const end = new Date(timeEnd)
          const now = new Date()
          const yesterday = new Date(now)
          yesterday.setDate(yesterday.getDate() - 1)
          yesterday.setHours(0, 0, 0, 0)
          const yesterdayEnd = new Date(yesterday)
          yesterdayEnd.setHours(23, 59, 59, 999)
          
          // 判断是否是昨天
          if (start.getTime() >= yesterday.getTime() && end.getTime() <= yesterdayEnd.getTime()) {
            return 'yesterday'
          }
          
          // 判断是否是最近7天
          const sevenDaysAgo = new Date(now)
          sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7)
          if (start.getTime() >= sevenDaysAgo.getTime()) {
            return 'recent'
          }
          
          // 判断是否是上月
          const lastMonthStart = new Date(now.getFullYear(), now.getMonth() - 1, 1)
          const lastMonthEnd = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999)
          if (start.getTime() >= lastMonthStart.getTime() && end.getTime() <= lastMonthEnd.getTime()) {
            return 'last_month'
          }
        }
        
        return 'custom'
      }
      
      // 处理 data_quality_monitor 模板：重建 time_range 并确保所有必需字段存在
      if (form.template_code === 'data_quality_monitor') {
        // 优先从 source_tables 中获取时间范围信息（最可靠）
        if (form.params.source_tables && typeof form.params.source_tables === 'object') {
          const sourceTables = form.params.source_tables
          if (sourceTables.time_range_type) {
            form.params.time_range = {
              time_range_type: sourceTables.time_range_type,
              time_start: sourceTables.time_start || null,
              time_end: sourceTables.time_end || null
            }
          }
        } 
        // 如果 source_tables 中没有，尝试从顶层参数中构建
        else if (form.params.time_start || form.params.time_end) {
          const timeRangeType = inferTimeRangeType(
            form.params.time_start,
            form.params.time_end,
            form.params.time_range_type
          )
          
          form.params.time_range = {
            time_range_type: timeRangeType,
            time_start: form.params.time_start || null,
            time_end: form.params.time_end || null
          }
        }
        // 如果都没有，使用默认值
        else {
          form.params.time_range = {
            time_range_type: 'all',
            time_start: null,
            time_end: null
          }
        }
        
        // 确保 display_fields 存在
        if (!Array.isArray(form.params.display_fields)) {
          form.params.display_fields = []
        }
        
        // 确保 field_labels 存在且是对象类型（保留已有的自定义标签）
        if (!form.params.field_labels || typeof form.params.field_labels !== 'object') {
          form.params.field_labels = {}
        }
      }
      // 处理 generic_data_quality_monitor 模板：确保参数结构正确
      else if (form.template_code === 'generic_data_quality_monitor') {
        // 确保 source_tables 存在且结构正确
        if (!form.params.source_tables || typeof form.params.source_tables !== 'object') {
          form.params.source_tables = {
            data_source_id: null,
            database_name: '',
            table_names: [],
            tables: [
              {
                table_name: '',
                distinct_field: 'id',
                time_field: 'etl_date',
                use_distinct: true
              }
            ],
            time_range_type: 'all',
            time_start: null,
            time_end: null
          }
        }
        
        // 确保 target_table_config 存在且结构正确
        if (!form.params.target_table_config || typeof form.params.target_table_config !== 'object') {
          form.params.target_table_config = {
            data_source_id: null,
            database_name: '',
            table_name: '',
            join_field: 'id',
            time_field: 'etl_date',
            filter_conditions: [],
            stat_fields: {}
          }
        } else {
          // 确保 filter_conditions 是数组
          if (!Array.isArray(form.params.target_table_config.filter_conditions)) {
            form.params.target_table_config.filter_conditions = []
          }
          // 确保 stat_fields 是对象
          if (!form.params.target_table_config.stat_fields || typeof form.params.target_table_config.stat_fields !== 'object') {
            form.params.target_table_config.stat_fields = {}
          }
        }
        
        // 确保 filter_rules 存在且结构正确
        if (!form.params.filter_rules || typeof form.params.filter_rules !== 'object') {
          form.params.filter_rules = {
            sync_rate_threshold: 80
          }
        }
        
        // 确保 display_fields 存在
        if (!Array.isArray(form.params.display_fields)) {
          form.params.display_fields = [
            'source_total_count',
            'target_total_count',
            'sync_rate',
            'data_status'
          ]
        }
        
        // 确保 field_labels 存在且是对象类型
        if (!form.params.field_labels || typeof form.params.field_labels !== 'object') {
          form.params.field_labels = {
            source_total_count: '源表总数',
            target_total_count: '目标表总数',
            sync_rate: '同步率',
            data_status: '数据状态'
          }
        }

        // 重建时间范围对象，优先使用 source_tables 中的时间配置
        const sourceTablesConfig = form.params.source_tables
        const timeRangeType =
          sourceTablesConfig?.time_range_type ||
          form.params.time_range_type ||
          'all'
        const timeStart =
          sourceTablesConfig?.time_start ??
          form.params.time_start ??
          null
        const timeEnd =
          sourceTablesConfig?.time_end ??
          form.params.time_end ??
          null

        form.params.time_range = {
          time_range_type: timeRangeType,
          time_start: timeStart,
          time_end: timeEnd
        }
      }
      // 处理 cps_data_quality_monitor 模板：重建 time_filter 并确保所有必需字段存在
      else if (form.template_code === 'cps_data_quality_monitor') {
        // 从顶层参数中重建 time_filter
        const timeStart = form.params.time_start
        const timeEnd = form.params.time_end
        const timeRangeType = inferTimeRangeType(
          timeStart,
          timeEnd,
          form.params.time_range_type
        )
        
        form.params.time_filter = {
          time_range_type: timeRangeType,
          time_start: timeStart || null,
          time_end: timeEnd || null
        }
        
        // 确保 platform_selection 存在且结构正确
        if (!form.params.platform_selection || typeof form.params.platform_selection !== 'object') {
          form.params.platform_selection = {
            selected_platforms: form.params.selected_platforms || ['dy'],
            include_summary: form.params.include_summary !== undefined ? form.params.include_summary : true
          }
          // 如果顶层有这些字段，删除它们（已经移到 platform_selection 中）
          delete form.params.selected_platforms
          delete form.params.include_summary
        } else {
          // 确保 platform_selection 的字段完整
          if (!Array.isArray(form.params.platform_selection.selected_platforms)) {
            form.params.platform_selection.selected_platforms = form.params.platform_selection.selected_platforms || ['dy']
          }
          if (form.params.platform_selection.include_summary === undefined) {
            form.params.platform_selection.include_summary = true
          }
        }
        
        // 确保 data_source_config 存在且结构正确
        if (!form.params.data_source_config || typeof form.params.data_source_config !== 'object') {
          form.params.data_source_config = {
            data_source_id: form.params.data_source_id || null
          }
          // 如果顶层有 data_source_id，删除它（已经移到 data_source_config 中）
          delete form.params.data_source_id
        }
        
        // 确保 threshold_config 存在且结构正确
        if (!form.params.threshold_config || typeof form.params.threshold_config !== 'object') {
          form.params.threshold_config = {
            sync_rate_threshold: form.params.sync_rate_threshold !== undefined ? form.params.sync_rate_threshold : 80
          }
          // 如果顶层有 sync_rate_threshold，删除它（已经移到 threshold_config 中）
          delete form.params.sync_rate_threshold
        }
        
        // 确保 display_fields 存在
        if (!Array.isArray(form.params.display_fields)) {
          form.params.display_fields = []
        }
        
        // 确保 field_labels 存在且是对象类型（保留已有的自定义标签）
        if (!form.params.field_labels || typeof form.params.field_labels !== 'object') {
          form.params.field_labels = {}
        }
      }
    }
    
    componentLogger.info('加载配置详情成功', { 
      config_id: configId, 
      template_code: form.template_code,
      params_keys: Object.keys(form.params),
      params: form.params,
      source_tables: form.params.source_tables,
      time_range: form.params.time_range,
      time_filter: form.params.time_filter,
      platform_selection: form.params.platform_selection,
      data_source_config: form.params.data_source_config,
      threshold_config: form.params.threshold_config,
      display_fields: form.params.display_fields,
      field_labels: form.params.field_labels,
      data_source_id: form.params.source_tables?.data_source_id || form.params.data_source_config?.data_source_id
    })
    notificationForm.send_notification = !!data.notify_on_success
    notificationForm.channels = data.notification_channels || (data.wecom_webhook_id ? ['wecom'] : [])
    notificationForm.webhook_id = data.wecom_webhook_id || null
  } catch (error) {
    componentLogger.error('加载配置详情失败', error)
    ElMessage.error('加载配置详情失败')
  } finally {
    loading.value = false
  }
}

watch(
  () => form.template_code,
  (code, prev) => {
    if (!code || code === prev || !internalVisible.value) return
    form.params = {}
  }
)

const handleParamsChange = (value: Record<string, any>) => {
  form.params = value
}

const buildNotificationPayload = () => {
  if (!notificationForm.send_notification) {
    return {
      notify_on_success: false,
      notifications: []
    }
  }
  const notifications: any[] = []
  if (notificationForm.channels.includes('wecom') && notificationForm.webhook_id) {
    notifications.push({
      channel: 'wecom',
      enabled: true,
      webhook_id: notificationForm.webhook_id,
      wecom_mention: {
        to_user: notificationForm.wecom_mentioned_list
          ? notificationForm.wecom_mentioned_list.split(',').map((item) => item.trim()).filter(Boolean)
          : [],
        to_party: [],
        to_tag: [],
        is_all: notificationForm.wecom_mentioned_all
      }
    })
  }
  return {
    notify_on_success: notifications.length > 0,
    notifications
  }
}

const normalizeParams = () => {
  const normalized = JSON.parse(JSON.stringify(form.params || {}))
  const timeRange = normalized.time_filter || normalized.time_range
  
  // 对于 data_quality_monitor 和 generic_data_quality_monitor 模板，确保时间范围同步到 source_tables 和 target_table_config
  if ((form.template_code === 'data_quality_monitor' || form.template_code === 'generic_data_quality_monitor') && timeRange) {
    // 同步时间范围到 source_tables（后端需要这些字段生成SQL）
    if (normalized.source_tables && typeof normalized.source_tables === 'object') {
      normalized.source_tables.time_range_type = timeRange.time_range_type
      normalized.source_tables.time_start = timeRange.time_range_type === 'all' ? null : timeRange.time_start
      normalized.source_tables.time_end = timeRange.time_range_type === 'all' ? null : timeRange.time_end
    }
    
    // 同步时间范围到 target_table_config（后端需要这些字段生成SQL）
    if (normalized.target_table_config && typeof normalized.target_table_config === 'object') {
      normalized.target_table_config.time_range_type = timeRange.time_range_type
      normalized.target_table_config.time_start = timeRange.time_range_type === 'all' ? null : timeRange.time_start
      normalized.target_table_config.time_end = timeRange.time_range_type === 'all' ? null : timeRange.time_end
    }
  }
  
  if (timeRange) {
    normalized.time_start = timeRange.time_range_type === 'all' ? null : timeRange.time_start
    normalized.time_end = timeRange.time_range_type === 'all' ? null : timeRange.time_end
    // 删除 time_range 和 time_filter 对象，因为已经提取到顶层
    // 但保留 source_tables 和 target_table_config 中的时间字段，因为后端需要它们来生成 SQL
    delete normalized.time_range
    delete normalized.time_filter
  }
  
  return normalized
}

const handleSubmit = async () => {
  if (!form.config_name) {
    ElMessage.warning('请填写报表标题')
    return
  }
  if (!form.template_code) {
    ElMessage.warning('请选择报表模板')
    return
  }

  const templateValid = await formCoreRef.value?.validate?.()
  if (templateValid === false) {
    activeTab.value = 'template'
    return
  }

  const notifyPayload = buildNotificationPayload()

  const payload = {
    config_name: form.config_name,
    template_code: form.template_code,
    is_active: form.is_active,
    schedule_enabled: form.schedule_enabled,
    schedule_cron: form.schedule_enabled ? form.schedule_cron : null,
    output_formats: filterOutputFormats(form.output_formats),
    notify_on_success: notifyPayload.notify_on_success,
    notifications: notifyPayload.notifications,
    params: normalizeParams()
  }

  saving.value = true
  try {
    if (isEdit.value && props.configId) {
      await api.put(`/reports/configs/${props.configId}`, payload)
      ElMessage.success('配置更新成功')
    } else {
      await api.post('/reports/configs', payload)
      ElMessage.success('配置创建成功')
    }
    componentLogger.info('保存配置成功', { template: form.template_code })
    emit('saved')
    handleClose()
  } catch (error: any) {
    componentLogger.error('保存配置失败', error)
    ElMessage.error(error?.response?.data?.message || '保存失败')
  } finally {
    saving.value = false
  }
}

const handleClose = () => {
  internalVisible.value = false
  resetForm()
}

const handleScheduleToggle = (enabled: boolean) => {
  if (!enabled) {
    form.schedule_cron = ''
    cronValid.value = false
    cronError.value = ''
    cronNextRuns.value = []
    cronReadable.value = ''
    if (cronDebounceTimer) {
      clearTimeout(cronDebounceTimer)
      cronDebounceTimer = null
    }
    return
  }
  nextTick(() => {
    cronInputRef.value?.focus?.()
    if (form.schedule_cron) {
      handleCronInputChange()
    }
  })
}

const handleCronInputChange = () => {
  cronError.value = ''
  cronReadable.value = ''
  cronNextRuns.value = []
  cronValid.value = false
  
  if (cronDebounceTimer) {
    clearTimeout(cronDebounceTimer)
  }
  
  cronDebounceTimer = setTimeout(() => {
    validateCronFromServer()
  }, 300)
}

const validateCronFromServer = async () => {
  const expr = (form.schedule_cron || '').trim()
  if (!expr) {
    cronValid.value = false
    return
  }
  
  try {
    const response = await api.get('/reports/cron/validate', {
      params: { expr, n: 3 }
    })
    
    if (response.data.success) {
      const data = response.data.data
      cronValid.value = !!data.valid
      cronError.value = data.valid ? '' : (data.message || '表达式无效')
      cronNextRuns.value = data.next_runs || []
      cronReadable.value = data.readable || ''
    } else {
      cronValid.value = false
      cronError.value = response.data.message || '校验失败'
    }
  } catch (error: any) {
    cronValid.value = false
    cronError.value = error?.response?.data?.message || error?.message || '校验异常'
    cronNextRuns.value = []
    cronReadable.value = ''
  }
}

const applyCronPreset = (cronExpr: string) => {
  form.schedule_cron = cronExpr
  // 清空验证状态，等待输入变化触发验证
  cronValid.value = false
  cronError.value = ''
  cronNextRuns.value = []
  cronReadable.value = ''
  
  // 立即触发验证
  if (cronDebounceTimer) {
    clearTimeout(cronDebounceTimer)
  }
  validateCronFromServer()
}

watch(
  () => props.modelValue,
  async (visible, oldVisible) => {
    if (visible) {
      // 对话框打开时，重置 tab 并加载数据
      activeTab.value = 'base'
      await ensureBaseDataReady()
      if (props.configId) {
        // 每次都重新加载数据，确保获取最新状态
        await loadConfigDetail(props.configId)
      } else {
        resetForm()
      }
    } else if (oldVisible !== undefined) {
      // 对话框从可见变为不可见时，重置表单
      // 注意：使用 oldVisible !== undefined 避免初始化时误触发
      resetForm()
    }
  },
  { immediate: false }
)

watch(
  () => props.configId,
  async (newId, oldId) => {
    // 只有在对话框可见时才处理 configId 变化
    if (!internalVisible.value) {
      return
    }
    // 如果 configId 变为 null 或 undefined，重置表单
    if (!newId) {
      resetForm()
      return
    }
    // 如果 configId 真的变化了（不是 undefined 到同一个值的初始化），重新加载
    // 注意：如果 oldId === undefined，说明是第一次设置，此时应该由 modelValue 的 watch 来处理
    if (oldId !== undefined && newId !== oldId) {
      await ensureBaseDataReady()
      await loadConfigDetail(newId)
    }
  }
)

// 组件销毁时清理定时器
onBeforeUnmount(() => {
  if (cronDebounceTimer) {
    clearTimeout(cronDebounceTimer)
    cronDebounceTimer = null
  }
})
</script>

<style scoped>
.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.header-text h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.header-text p {
  margin: 4px 0 0;
  color: #909399;
  font-size: 13px;
}

.config-tabs {
  min-height: 420px;
}

.form-section {
  margin-bottom: 24px;
  padding: 24px;
  border: 1px solid #e4e7ed;
  border-radius: 12px;
  background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  transition: all 0.3s ease;
}

.form-section:hover {
  border-color: #c0c4cc;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
  transform: translateY(-1px);
}

.section-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  margin-bottom: 20px;
  color: #1f2937;
  font-size: 16px;
  padding-bottom: 12px;
  border-bottom: 2px solid #f0f0f0;
  position: relative;
}

.section-title::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 60px;
  height: 2px;
  background: linear-gradient(90deg, #409eff, #67c23a);
  border-radius: 1px;
}

.section-title .el-icon {
  font-size: 18px;
  color: #409eff;
}

.form-section :deep(.el-form-item) {
  margin-bottom: 20px;
}

.form-section :deep(.el-form-item__label) {
  font-weight: 500;
  color: #374151;
  line-height: 32px;
}

.form-section :deep(.el-select) {
  width: 100%;
}

.form-section :deep(.el-select .el-input__inner) {
  border-radius: 8px;
  border: 1px solid #d1d5db;
  transition: all 0.3s ease;
}

.form-section :deep(.el-select .el-input__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
}

.form-section :deep(.el-switch) {
  --el-switch-on-color: #409eff;
}

.form-section :deep(.el-switch__core) {
  border-radius: 12px;
}

.form-section :deep(.el-checkbox) {
  margin-right: 16px;
  margin-bottom: 8px;
}

.form-section :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: #409eff;
  border-color: #409eff;
}

.schedule-subsection {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid #e4e7ed;
}

.schedule-subsection-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 16px;
  font-weight: 600;
  color: #1f2937;
  font-size: 16px;
}

.schedule-icon {
  color: #409eff;
  font-size: 18px;
}

.schedule-switch-wrapper {
  margin-left: auto;
  display: flex;
  align-items: center;
}

.schedule-content {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.cron-input {
  width: 100%;
}

.cron-input :deep(.el-input__wrapper) {
  border-radius: 8px;
  border: 1px solid #d1d5db;
  transition: all 0.3s ease;
  box-shadow: none;
}

.cron-input :deep(.el-input__inner) {
  border: none;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
  box-shadow: none;
}

.cron-input :deep(.el-input__wrapper.is-focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
}

.cron-input :deep(.el-input.is-disabled .el-input__wrapper) {
  background-color: #f5f7fa;
  border-color: #e4e7ed;
  cursor: not-allowed;
}

.cron-input :deep(.el-input.is-disabled .el-input__inner) {
  color: #c0c4cc;
  cursor: not-allowed;
}

.cron-validation {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.cron-status {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.cron-readable {
  font-size: 12px;
  color: #606266;
  font-weight: 500;
}

.cron-next-runs {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background-color: #f0f9ff;
  border: 1px solid #bfdbfe;
  border-radius: 6px;
  font-size: 12px;
  color: #1e40af;
}

.cron-next-runs .el-icon {
  font-size: 14px;
  color: #409eff;
}

.cron-quick-presets {
  margin-top: 12px;
  padding: 12px;
  background-color: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
}

.quick-presets-header {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
  font-weight: 500;
  color: #606266;
  font-size: 13px;
}

.quick-presets-header .el-icon {
  font-size: 14px;
  color: #409eff;
}

.quick-presets-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.quick-presets-buttons .el-button {
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.quick-presets-buttons .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}

.cron-tip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background-color: #f0f9ff;
  border: 1px solid #bfdbfe;
  border-radius: 6px;
  font-size: 12px;
  color: #1e40af;
  margin-top: 8px;
}

.cron-tip .el-icon {
  font-size: 14px;
  color: #409eff;
}

.template-name {
  display: block;
  font-weight: 500;
  color: #303133;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
</style>

